using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using Spine;
using Spine.Unity;
using System.IO;


/// <summary>
/// 帧动画的帧信息
/// </summary>
public class SpriteAniFrameInfoEditor
{
    public Sprite Sprite;
    public string TimeStr;

    public int Sort;
}

/// <summary>
/// 帧动画信息
/// </summary>
public class SpriteAniInfoEditor
{
    public string AniName;
    public float Duration;
    public List<SpriteAniFrameInfoEditor> FrameList;

    public override string ToString()
    {
        return AniName;
    }
}

/// <summary>
/// 序列帧动画制作界面
/// </summary>
public class SpriteAniEditorPanel : EditorWindow
{
    Texture2D textureAtlas;       //对应图集
    GameObject skeleRes;

    List<SpriteAniInfoEditor> aniInfoList = new List<SpriteAniInfoEditor>();

    public static void Open()
    {
        SpriteAniEditorPanel window = (SpriteAniEditorPanel)EditorWindow.GetWindow(typeof(SpriteAniEditorPanel));
        window.Show();
    }

    public static void Open(Texture2D texture)
    {
        SpriteAniEditorPanel window = (SpriteAniEditorPanel)EditorWindow.GetWindow(typeof(SpriteAniEditorPanel));
        window.Show();


        //首次打开默认选下Spine物体
        string texturePath = AssetDatabase.GetAssetPath(texture);
        string dirName = Path.GetDirectoryName(texturePath);
        string[] gamePathArr = Directory.GetFiles(Path.GetDirectoryName(dirName), "*.prefab", SearchOption.TopDirectoryOnly);
        GameObject skeleGame = null;
        foreach (string gamePath in gamePathArr)
        {
            GameObject game = AssetDatabase.LoadAssetAtPath<GameObject>(gamePath);
            if (game != null)
            {
                if (game.GetComponentInChildren<SkeletonAnimation>() != null)
                {
                    skeleGame = game;
                    break;
                }
            }
        }
        window.textureAtlas = texture;
        window.skeleRes = skeleGame;

        //默认生成动画信息
        if (texture != null && skeleGame != null)
        {
            List<SpriteAniInfoEditor> aniList = SpriteAniMaker.MakeAniInfo(skeleGame, texture);

            List<SpriteAniInfo> copyAniList = null;
            string resName = Path.GetFileNameWithoutExtension(texturePath);
            string resFullPath = $"{dirName}/{resName}{SpriteAniMaker.SuffixName}.prefab";
            GameObject spRes = AssetDatabase.LoadAssetAtPath<GameObject>(resFullPath);
            if (spRes != null)
            {
                var aniInfo = spRes.GetComponentInChildren<SpriteAnimation>();
                if (aniInfo != null)
                {
                    copyAniList = aniInfo.ClipList;
                }
            }
            if (copyAniList != null)
            {
                void CopyAniInfo(List<SpriteAniInfoEditor> now, List<SpriteAniInfo> ori)
                {
                    Dictionary<string, Dictionary<string, float>> oriInfo = new Dictionary<string, Dictionary<string, float>>();
                    foreach (var clip in ori)
                    {
                        if (!oriInfo.ContainsKey(clip.AniName))
                        {
                            oriInfo[clip.AniName] = new Dictionary<string, float>();
                        }
                        foreach (var fram in clip.FrameList)
                        {
                            if (fram.Sprite != null)
                            {
                                oriInfo[clip.AniName][fram.Sprite.name] = fram.Time;
                            }
                        }
                    }

                    foreach (var clip in now)
                    {
                        if (oriInfo.TryGetValue(clip.AniName, out Dictionary<string, float> frameDic))
                        {
                            foreach (var fram in clip.FrameList)
                            {
                                if (frameDic.TryGetValue(fram.Sprite.name, out float time))
                                {
                                    fram.TimeStr = time.ToString();
                                }
                            }
                        }
                    }
                }
                CopyAniInfo(aniList, copyAniList);
            }
            window.aniInfoList = aniList;

        }
    }

    private void OnGUI()
    {
        GUILayout.BeginHorizontal();
        Texture2D textureTemp = (Texture2D)EditorGUI.ObjectField(EditorGUILayout.GetControlRect(), "图集资源:", textureAtlas, typeof(Texture2D), false);
        if (textureTemp != textureAtlas)
        {
            textureAtlas = textureTemp;
        }
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        GameObject tempGame = (GameObject)EditorGUI.ObjectField(EditorGUILayout.GetControlRect(), "Spine动画物体:", skeleRes, typeof(GameObject), false);
        if (tempGame != skeleRes)
        {
            skeleRes = tempGame;
        }
        GUILayout.EndHorizontal();


        if (GUILayout.Button("重新生成动画信息"))
        {
            if (textureAtlas == null) { EditorUtility.DisplayDialog("问题", "没有图集", "ok"); return; }
            if (skeleRes == null) { EditorUtility.DisplayDialog("问题", "没有Spine动画物体", "ok"); return; }
            var skeleAni = skeleRes.GetComponentInChildren<SkeletonAnimation>();
            if (skeleAni == null) { EditorUtility.DisplayDialog("问题", "物体上没找到动画组件", "ok"); return; }

            aniInfoList = SpriteAniMaker.MakeAniInfo(skeleRes, textureAtlas);
        }

        foreach (var aniInfo in aniInfoList)
        {
            GUILayout.Label(aniInfo.AniName);

            GUILayout.BeginHorizontal();
            GUILayout.Space(30);
            GUILayout.Label($"持续时间:{aniInfo.Duration}秒");
            GUILayout.EndHorizontal();

            foreach (var frameInfo in aniInfo.FrameList)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Space(30);
                EditorGUI.ObjectField(EditorGUILayout.GetControlRect(), frameInfo.Sprite, typeof(Sprite), false);
                frameInfo.TimeStr = GUILayout.TextField(frameInfo.TimeStr);
                GUILayout.EndHorizontal();
            }
        }

        if (GUILayout.Button("制作"))
        {

            if (aniInfoList == null || aniInfoList.Count == 0) { EditorUtility.DisplayDialog("问题", "没有动画信息", "ok"); return; }

            string path = AssetDatabase.GetAssetPath(textureAtlas);
            string dirPath = Path.GetDirectoryName(path);
            SpriteAniMaker.CreateSpriteAniGame(skeleRes, aniInfoList, dirPath, skeleRes.name);
        }
    }

}
